"""
Case Type   : dsscmd交互式
Case Name   : 交互式模式下，交互节点异常
Create At   : 2024/10
Owner       : haomeng
Description :
    1、构造交互节点异常
    2、进入交互模式，输出部分常规操作
    3、恢复异常节点
    4、进入交互模式，输入部分常规操作
    5、恢复环境
Expect      :
    1、停止节点成功
    2、操作失败，Failed to get uds connection
    3、拉起节点成功
    4、操作成功
    5、恢复环境成功
History     :
"""


import os
import time
import unittest

from testcase.utils.Logger import Logger
from testcase.utils.CommonSH import CommonSH
from testcase.utils.Constant import Constant
from yat.test import Node
from yat.test import macro


class DsscmdInteractive(unittest.TestCase):

    def setUp(self):
        self.log = Logger()
        self.log.info(f'----{os.path.basename(__file__)} start----')
        self.node = Node('PrimaryDbUser')
        self.pri_sh = CommonSH('PrimaryDbUser')
        self.constant = Constant()
        self.directory = 'dsscmd_file'
        self.file = 'file.txt'
        self.new_file1 = 'new_file1.txt'
        self.new_file2 = 'new_file2.txt'

    def test_dsscmd(self):
        text = '-----step1:构造交互节点异常  expect:停止节点成功-----'
        self.log.info(text)

        stop_node = self.pri_sh.exec_cm_ctl('stop -n 1')
        self.log.info(stop_node)
        self.assertIn(self.constant.cm_stop_node_success_msg, stop_node, '停止节点失败')
        time.sleep(30)

        text = '-----step2:进入交互式模式，执行部分常规命令   expect:失败,Failed to get uds connection-----'
        self.log.info(text)

        param_list1 = [f'mkdir -p +data -d {self.directory}',
                       f'ls -p +data/{self.directory}',
                       f'touch -p +data/{self.directory}/{self.file}',
                       f'ls -p +data/{self.directory}/{self.file}',
                       f'find -p +data -n {self.file}',
                       f'rmdir -p +data/{self.directory} -r']
        cmd = f'''dsscmd -i'''

        execute_cmd1 = f'''source {macro.DB_ENV_PATH};
                     expect <<EOF
                     set timeout 3
                     spawn {cmd}
                     expect "dsscmd>"
                     send "{param_list1[0]}\\n"
                     expect "dsscmd>"
                     send "{param_list1[1]}\\n"
                     expect "dsscmd>"
                     send "{param_list1[2]}\\n"
                     expect "dsscmd>"
                     send "{param_list1[3]}\\n"
                     expect "dsscmd>"
                     send "{param_list1[4]}\\n"
                     expect "dsscmd>"
                     send "{param_list1[5]}\\n"
                     expect "dsscmd>"
                     send "exit\\n"
                     expect eof\n''' + '''EOF'''
        self.log.info(execute_cmd1)
        res1 = self.node.sh(execute_cmd1).result()
        self.log.info(res1)
        self.assertEqual(6, res1.count('Failed to get uds connection'), '操作命令执行成功')

        text = '-----step3:恢复交互节点dssserver进程正常   expect:恢复成功-----'
        self.log.info(text)

        start_node = self.pri_sh.exec_cm_ctl('start -n 1')
        self.log.info(start_node)
        self.assertIn(self.constant.cm_start_node_success_msg, start_node, '恢复节点失败')

        text = '-----step4:进入交互式模式，执行部分常规操作   expect:执行成功-----'
        self.log.info(text)

        for param in param_list1:
            execute_cmd2 = f'''source {macro.DB_ENV_PATH};
                         expect <<EOF
                         set timeout 3
                         spawn {cmd}
                         expect "dsscmd>"
                         send "{param}\\n"
                         expect "dsscmd>"
                         send "exit\\n"
                         expect eof\n''' + '''EOF'''
            self.log.info(execute_cmd2)
            res2 = self.node.sh(execute_cmd2).result()
            self.log.info(res2)
            self.assertNotIn('Failed to get uds connection', res2, '连接dss失败')

    def tearDown(self):
        text = '-----step5:恢复环境  expect:恢复环境成功-----'
        self.log.info(text)

        status = self.pri_sh.exec_cm_ctl(mode='query', param='-Cv')
        self.log.info(status)
        p_status = status.splitlines()[-1].split('|')[0].split('6001')[-1]
        if 'Primary' in p_status and "cluster_state   : Normal" in status:
            self.log.info('---集群状态正常，无需恢复为初始状态---')
        else:
            recovery = self.pri_sh.exec_cm_ctl(mode='switchover', param='-a')
            self.log.info(recovery)

            self.assertIn(self.constant.cm_switchover_success_msg, recovery,
                          '执行失败' + text)

        status = self.pri_sh.exec_cm_ctl(mode='query', param='-Cv')
        self.log.info(status)

        self.assertIn('cluster_state   : Normal', status, '执行失败' + text)
        self.assertIn('P Primary Normal',
                      status.splitlines()[-1].split('|')[0].split('6001')[-1],
                      '执行失败' + text)
        self.assertIn('S Standby Normal',
                      status.splitlines()[-1].split('|')[1].split('6002')[-1],
                      '执行失败' + text)
        self.log.info(f'----{os.path.basename(__file__)} end----')
